package com.xunwulian.cmpp.client.handler;

import com.alibaba.dubbo.config.annotation.Reference;
import com.google.common.base.Preconditions;
import com.xunwulian.api.iface.SmsAPI;
import com.xunwulian.base.constant.ConstantBean;
import com.xunwulian.base.entity.AppEntity;
import com.xunwulian.cmpp.pdu.*;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class CmppClientIoHandler extends IoHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(CmppClientIoHandler.class);

    private AppEntity app;

    @Reference
    private SmsAPI smsAPI;

    public CmppClientIoHandler(){}

    public void setApp(AppEntity appEntity) {
        Preconditions.checkNotNull(appEntity, "app show not be null!");
        app = appEntity;
    }

    @Override
    public void sessionOpened(IoSession session) {
        logger.info("Session " + session.getId() + " is opened");
        logger.info("发送连接请求，connectRequest");
        Connect connectRequest = new Connect(app.getServerClientId(), app.getServerPassword());
        session.write(connectRequest);
        session.resumeRead();

        Thread t = new Thread(new ActiveThread(session));
        t.setDaemon(true);
        t.start();
        session.resumeRead();
    }

    @Override
    public void sessionCreated(IoSession session) {
        try {
            logger.info("Session创建成功, sessionId:" + session.getId());
            session.setAttribute(ConstantBean.OPEN);
            session.suspendRead();
            session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) {

//        try {
//            super.sessionIdle(session, status);
//            if ((System.currentTimeMillis() - lastActiveTime) > CmppConstant.HEARTBEAT_INTERVAL) {
//                ActiveTest activeTest = new ActiveTest();
//                activeTest.timeStamp = Integer.valueOf(new SimpleDateFormat("MMddHHmmss").format(new Date()));
//                // 心跳检测
//                logger.info("发送心跳探测请求：ActiveTest");
//                session.write(activeTest);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    @Override
    public void messageSent(IoSession session, Object message) {
        try {
            super.messageSent(session, message);
            logger.info("message sent:" + message.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
        logger.info("exceptionCaught:" + cause.getMessage());
        if (!(cause instanceof IOException)) {
            logger.error("Exception: ", cause);
        } else {
            logger.info("I/O error: " + cause.getMessage());
        }
        cause.printStackTrace();
        session.close(true);
    }

//    @Override
//    public void inputClosed(IoSession session) {
//        try {
//            super.inputClosed(session);
//            logger.info("input closed" + session.getId());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

    @Override
    public void sessionClosed(IoSession session) {
        try {
            session.removeAttribute(ConstantBean.OPEN);
            logger.info("Session closed, session.getId(): " + session.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void messageReceived(IoSession session, Object message) {
        if (message instanceof ConnectResp) {
            processConnectResp(session, (ConnectResp) message);
        } else if (message instanceof ActiveTestResp) {
            // 链路检测应答报文
            processActiveTestResp((ActiveTestResp) message);
        } else if (message instanceof ActiveTest) {
            // 链路检测报文
            processActiveTestReq(session, (ActiveTest) message);
        } else if (message instanceof QueryResp) {
            processQuery((QueryResp) message);
        } else  if (message instanceof SubmitResp) {
            // 提交短信应答报文
            processSubmitResp((SubmitResp) message);
        } else if (message instanceof Deliver) {
            // ISMG向SP提交短信
            processDeliver(session, (Deliver) message);
        } else {
            logger.warn("Unexpected PDU received! ");
        }
        ActiveThread.lastActiveTime = System.currentTimeMillis();
    }

    private void processConnectResp(IoSession session, ConnectResp conrsp) {
        logger.info("接收到连接应答报文conrsp :" + conrsp.dump());
        if (conrsp.getStatus() != 0) {
            session.close(true);
        }
    }

    private void processActiveTestResp(ActiveTestResp activeTestRsp) {
        logger.info("接收心跳应答报文，activeTestRsp");
        // 更新心跳线程的更新时间
        ActiveThread.lastActiveTime = System.currentTimeMillis();
    }

    private void processActiveTestReq(IoSession session, ActiveTest activeTest) {
        logger.info("接收链路检测请求报文，" + "activeTest");
        ActiveTestResp activeTestResp = (ActiveTestResp) activeTest.createResponse();
        session.write(activeTestResp);
        logger.info("发送链路检测应答报文，" + "activeTestResp");
    }

    private void processQuery(QueryResp queryresp) {
        logger.info("接收查询应答报文，queryresp : [" + queryresp.dump() + "]");
        queryresp.getMo_scs();
    }

    private void processSubmitResp(SubmitResp subresp) {
        logger.info("短信发送应答报文，SEQ_ID:" + subresp.getSequenceNumber() + ", subresp : [" + subresp.dump() + "]");
//        SmsAPI smsAPI = new Consumer<SmsAPI>().getApi(SmsAPI.class, ConstantBean.XWL_GROUP,
//                app.getAppId(), app.getRegistryAddress());
        smsAPI.noticeReply(subresp.getSequenceNumber(), subresp.getResult(), "", "");
        logger.info("更新短信发送状态为成功，SEQ_ID:" + subresp.getSequenceNumber());
    }

    public void processDeliver(IoSession session, Deliver cmppDeliver) {
        DeliverResp cmppDeliverResp = (DeliverResp) cmppDeliver.createResponse();
        if (cmppDeliver.getIsReport() == 0) {
            // 接收到的短信写入库表
            logger.info("接收到短信报文, MSISDN:" + cmppDeliver.getSrcTermId()
                    + ", CONTENT:" + cmppDeliver.getMsgContent()
                    + ", SequenceNumber:" + cmppDeliver.getSequenceNumber()
                    + ", cmppDeliver.getSrcTermId():" + cmppDeliver.getSrcTermId()
                    + ", Deliver: [" + cmppDeliver.dump() + "]");
//            SmsAPI smsAPI = new Consumer<SmsAPI>().getApi(SmsAPI.class, ConstantBean.XWL_GROUP,
//                    app.getAppId(), app.getRegistryAddress());
            smsAPI.addSms(cmppDeliver.getSrcTermId(), cmppDeliver.getMsgContent(), cmppDeliver.getSequenceNumber());
        } else {
            // 接收到的短信报告不写入库表
            logger.info("接收到短信发送报告：sms_stat: [" + cmppDeliver.dump() + "]");
        }
        session.write(cmppDeliverResp);
        logger.info("发送短信应答报文，Deliver Resp，" + "cmppDeliverResp : [" + cmppDeliverResp.dump() + "]");
    }
}
